package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import com.easyaop.api.Arounds;
import com.easyaop.api.advisor.MethodPointcut;
import com.easyaop.core.AroundsImpl;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) throws Exception {
        
        Arounds around = AroundsImpl.getInstance();
        MethodPointcut pointcut = MethodPointcut.of(
                "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory", "invokeInitMethods",
                "(..)V");
        around.add(
                pointcut, (target, ars, join, call) -> {
                    long start = System.currentTimeMillis();
                    Object result = call.call();
                    long cost = System.currentTimeMillis() - start;
                    String beanName = ((String) ars[0]);
                    if (cost > 100) {
                        System.out.println("-- invokeInitMethods: " + cost + " - " + beanName);
                    }
                    return result;
                });

        MethodPointcut pointcut2 = MethodPointcut.of(
                "org.springframework.beans.factory.support.SimpleInstantiationStrategy", "instantiate", "(..)*");
        around.add(pointcut2, (target, ars, join, call) -> {
            long start = System.currentTimeMillis();
            Object result = call.call();
            long cost = System.currentTimeMillis() - start;
            String beanName = ((String) ars[1]);
            if (cost > 100) {
                System.out.println("-- instantiate: " + cost + " - " + beanName);
            }
            return result;
        });

        MethodPointcut pointcut3 = MethodPointcut.of(
                "org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata",
                "invokeInitMethods", "(..)*");
        around.add(pointcut3, (target, ars, join, call) -> {
            long start = System.currentTimeMillis();
            Object result = call.call();
            long cost = System.currentTimeMillis() - start;
            String beanName = ((String) ars[1]);
            if (cost > 100) {
                System.out.println("-- invokeInitMethods: " + cost + " - " + beanName);

            }
            return result;
        });

        MethodPointcut pointcut4 = MethodPointcut.of(
                "org.springframework.context.event.SimpleApplicationEventMulticaster", "doInvokeListener", "(..)*");
        around.add(pointcut4, (target, ars, join, call) -> {
            long start = System.currentTimeMillis();
            Object result = call.call();
            long cost = System.currentTimeMillis() - start;
            String beanClassName = ars[0].getClass().getName();
            if (cost > 100) {
                System.out.println("-- doInvokeListener: " + cost + " - " + beanClassName);
            }
            return result;
        });
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
    }

}
